package com.tutucms.common.system;

import com.tutucms.common.util.Arith;
import com.sun.management.OperatingSystemMXBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Title:SystemInfoUtil.java
 *
 * @author WangXuDong
 * @version 1.0
 */
public class SystemInfoUtil {
    private static final Logger log = LoggerFactory.getLogger(SystemInfoUtil.class);

    /**
     * 获取操作系统名称
     *
     * @return
     */
    public static String getOsName() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("os.name");
        return os;
    }

    /**
     * 获取操作系统用户名
     *
     * @return
     */
    public static String getOsUserName() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("user.name");
        return os;
    }

    /**
     * 获取机器名
     *
     * @return
     */
    public static String getmachineName() {
        String name = ManagementFactory.getRuntimeMXBean().getName();
        return name.split("@")[1];
    }

    /**
     * 获取操作系统用户目录
     *
     * @return
     */
    public static String getOsUserHome() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("user.home");
        return os;
    }

    /**
     * 获取操作系统版本
     *
     * @return
     */
    public static String getOsVersion() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("os.version");
        return os;
    }

    /**
     * 获取jdk版本
     */
    public static String getJDKVersion() {
        Properties prop = System.getProperties();
        String os = prop.getProperty("java.version");
        return os;
    }

    /**
     * 获取操作系统的内存使用百分比
     *
     * @return
     */
    public static String getMemeryPercent() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        // 总的计算机物理内存+虚拟内存
        //单位b
        long totalvirtualMemory = osmxb.getTotalSwapSpaceSize();
        // 剩余的计算机物理内存
        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize();
        Double compare = (1 - freePhysicalMemorySize * 1.0 / totalvirtualMemory) * 100;
        String str = compare.intValue() + "%";
        return str;
    }

    /**
     * 获取操作系统内存使用信息
     *
     * @return long[0]总大小单位kb, long[1]使用大小kb, long[2]剩余大小
     */
    public static long[] getMemeryInfo() {
        OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long[] retlong = new long[3];
        //总的虚拟内存加物理内存
        long totalvirtualMemory = osmxb.getTotalSwapSpaceSize() / 100;
        retlong[0] = totalvirtualMemory;
        // 剩余的物理内存
        long freePhysicalMemorySize = osmxb.getFreePhysicalMemorySize() / 100;
        retlong[2] = freePhysicalMemorySize;

        retlong[1] = totalvirtualMemory - freePhysicalMemorySize;
        return retlong;
    }

    /**
     * JAVA虚拟机使用的内存情况
     *
     * @return
     */
    public static String getJVMMemeryPercent() {
        Runtime rt = Runtime.getRuntime();
        //单位b
        long free = rt.freeMemory();
        long total = rt.totalMemory();
        Double compare = ((total - free) * 1.0 / total) * 100;
        String str = compare.intValue() + "%";
        return str;
    }

    /**
     * 获取各分区的使用百分比 其他单位kb
     *
     * @return key 盘符，value(String[0]总大小，String[1]，使用大小，String[2]剩余大小，String[3]使用百分比)
     */
    public static Map<String, String[]> getDisk() {
        Map<String, String[]> map = new HashMap<>();
        if(getOsName().toUpperCase().contains("WINDOW")) {
            for (char c = 'A'; c <= 'Z'; c++) {
                String dirName = c + ":/";
                File win = new File(dirName);
                if (win.exists()) {
                    long total = win.getTotalSpace() / 1024;
                    long free = win.getFreeSpace() / 1024;
                    Double compare = (1 - free * 1.0 / total) * 100;
                    String str = compare.intValue() + "%";
                    String[] strarr = new String[4];
                    strarr[0] = String.valueOf(total);
                    strarr[1] = String.valueOf(total - free);
                    strarr[2] = String.valueOf(free);
                    strarr[3] = str;
                    map.put(String.valueOf(c), strarr);
                }
            }
        }else {
            File file = new File(SystemInfoUtil.class.getClassLoader().getResource("").getPath());
            long total = file.getTotalSpace() / 1024;
            long free = file.getFreeSpace() / 1024;
            long used = total - free;
            double usage = ((double)used / (double)total * 100.0);
            usage = Arith.round(usage, 2);
            String [] strarr = new String[4];
            strarr[0] = String.valueOf(total);
            strarr[1] = String.valueOf(used);
            strarr[2] = String.valueOf(free);
            strarr[3] = String.valueOf(usage) + "%";
            map.put("root", strarr);
        }
        return map;
    }

    /**
     * 获取本机IP地址
     *
     * @return
     */
    public static String getHostAddress() {
        InetAddress ia = null;
        try {
            ia = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            log.warn("获取IP地址，可能存在多个虚拟网卡，我们尝试使用其他方式获取!");
            try {
                Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
                InetAddress ip;
                while (allNetInterfaces.hasMoreElements()) {
                    NetworkInterface netInterface = allNetInterfaces.nextElement();
                    if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                        continue;
                    } else {
                        Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
                        while (addresses.hasMoreElements()) {
                            ip = addresses.nextElement();
                            if (ip != null && ip instanceof Inet4Address) {
                                return ip.getHostAddress();
                            }
                        }
                    }
                }
            } catch (Exception e2) {
                log.error("IP地址获取失败", e);
            }
        }
        return ia.getHostAddress();
    }

    /**
     * 获取本机MAC地址
     *
     * @return
     */
    public static String getMacAddress() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            byte[] mac;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || !netInterface.isUp()) {
                    continue;
                } else {
                    mac = netInterface.getHardwareAddress();
                    if (mac != null) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < mac.length; i++) {
                            sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
                        }
                        if (sb.length() > 0) {
                            return sb.toString();
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("MAC地址获取失败", e);
        }
        return "";
    }

}
